﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Caching;
using System.Web.Security;
using mijiaxueche.Common;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace mijiaxueche.weixin.help
{
    public class wxHelper
    {
        public static string appid = ConfigurationManager.AppSettings["appid"];
        public static string secret = ConfigurationManager.AppSettings["secret"];
        public static string WxSsgId = ConfigurationManager.AppSettings["WxSsgId"];
        public static string msgUri = ConfigurationManager.AppSettings["msgUri"];
        public static string apiUri = ConfigurationManager.AppSettings["apiUri"];
        /// <summary>
        /// 验证微信签名
        /// </summary>
        /// * 将token、timestamp、nonce三个参数进行字典序排序
        /// * 将三个参数字符串拼接成一个字符串进行sha1加密
        /// * 开发者获得加密后的字符串可与signature对比，标识该请求来源于微信。
        /// <returns></returns>
        public static bool CheckSignature(string signature, string timestamp, string nonce, string Token)
        {
            string[] ArrTmp = { Token, timestamp, nonce };
            Array.Sort(ArrTmp);     //字典排序
            string tmpStr = string.Join("", ArrTmp);
            tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
            tmpStr = tmpStr.ToLower();
            if (tmpStr == signature)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// datetime转换为unixtime
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public static int ConvertDateTimeInt(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            return (int)(time - startTime).TotalSeconds;
        }
        /// <summary>
        /// 获取公众号的access_Token 由于接口存在调用次数限制进行缓存处理
        /// </summary>
        /// <returns></returns>
        public static string getToken()
        {
            string access_Token = "";

            if (HttpContext.Current.Cache["access_token"] != null)
            {
                access_Token = HttpContext.Current.Cache["access_token"].ToString();
            }
            else
            {
                return UpdateToken();
            }

            //测试token是否有效


            return access_Token;
        }

        public static string UpdateToken()
        {
            string access_Token = "";
            try
            {
                string strUri = string.Format(
                        "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}",
                        wxHelper.appid, wxHelper.secret);
                string json = GetTextByUrl.GetGZipEncodedHTMLContent(strUri, "");
                JObject ja = (JObject)JsonConvert.DeserializeObject(json);
                access_Token = ja["access_token"].ToString();
                int value = Convert.ToInt32(ja["expires_in"].ToString());
                HttpContext.Current.Cache.Insert("access_token", access_Token, null, DateTime.Now.AddSeconds(value - 60), Cache.NoSlidingExpiration);
            }
            catch (Exception e)
            {
                Logger.Error("获取公众号的access_Token出现异常：", e);
            }
            return access_Token;
        }

        /// <summary>
        /// 获取用户的二维码
        /// </summary>
        /// <param name="strUserId">用户编号</param>
        /// <returns></returns>
        public static string getUserShareErWeiMa(string strUserId)
        {
            string strErWeiMa = getWxticket("YHTJ_" + strUserId);

            //将二维码保存到本地
            string ewmUri = String.Format("https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={0}", strErWeiMa);
            string strImgName = Guid.NewGuid().ToString() + ".png";
            string strPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images\\UserShare\\");
            GetTextByUrl.SaveImg(ewmUri, strPath, strImgName);
            return strImgName;
        }

        public static string getWxticket(string parms)
        {
            string strUri = String.Format("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={0}", getToken());
            string strBody =
                String.Format(
                    "{{\"action_name\": \"QR_LIMIT_STR_SCENE\", \"action_info\": {{\"scene\": {{\"scene_str\": \"{0}\"}}}}}}", parms);
            string json = GetTextByUrl.webRequestPost(strUri, strBody);
            JObject ja = (JObject)JsonConvert.DeserializeObject(json);
            if (ja["errcode"] != null)
            {
                wxHelper.UpdateToken(); //刷新access_token
                return getWxticket(parms);
            }
            return ja["ticket"].ToString();
        }
        /// <summary>
        /// 生成临时图片
        /// </summary>
        /// <param name="parms"></param>
        /// <returns></returns>
        public static string getTempImg(string parms)
        {
            string strUri = String.Format("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={0}", getToken());
            string strBody =
                String.Format(
                    "{{\"expire_seconds\": 604800,\"action_name\": \"QR_LIMIT_STR_SCENE\", \"action_info\": {{\"scene\": {{\"scene_str\": \"{0}\"}}}}}}", parms);
            string json = GetTextByUrl.webRequestPost(strUri, strBody);
            Logger.Info("生成图片:json==" + json);
            JObject ja = (JObject)JsonConvert.DeserializeObject(json);
            if (ja["errcode"] != null)
            {
                wxHelper.UpdateToken(); //刷新access_token
                return getTempImg(parms);
            }
            string ticket = ja["ticket"].ToString();
            //将二维码保存到本地
            string ewmUri = String.Format("https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={0}", ticket);
            return ewmUri;
        }

        public static void Exists(string media_id)
        {
            string strImgUri = string.Format("https://api.weixin.qq.com/cgi-bin/media/get?access_token={0}&media_id={1}", wxHelper.getToken(), media_id);
            try
            {
                string strRes = GetTextByUrl.getDataFromUrl(strImgUri);
                JObject ja = (JObject)JsonConvert.DeserializeObject(strRes);
                if (ja["errcode"] != null)
                {
                    wxHelper.UpdateToken(); //刷新access_token
                }
            }
            catch (Exception)
            {
            }
        }

        /// <summary>
        /// 获取JS-SDK权限验证的签名
        /// </summary>
        /// <param name="timestamp"></param>
        /// <param name="nonceStr"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        private static string GetSignature(long timestamp, string nonceStr, string url)
        {
            try
            {
                var jsapi_ticket = wxGetAccessToken.getTicket();
                //对所有待签名参数按照字段名的ASCII 码从小到大排序
                var string1 = string.Format("jsapi_ticket={0}&noncestr={1}&timestamp={2}&url={3}", jsapi_ticket, nonceStr, timestamp, url);
                // 对string1进行sha1签名，得到signature
                var signature = FormsAuthentication.HashPasswordForStoringInConfigFile(string1, "SHA1");
                return signature;
            }
            catch
            {

                return string.Empty;
            }
        }

        public static string getconfig(string uri, string parms)
        {

            string timestamp = ConvertDateTimeInt(DateTime.Now).ToString();//时间戳 我是这样生成的
            //  var noncestr = "kjkjkjkjljkjjjjkj";//这里是随机字符串，可以自己写个算法之类的实现

            string signature = GetSignature(Convert.ToInt64(timestamp), timestamp, uri);//调取上面的获取signature的方法
            return string.Format(@"wx.config({{
                                   debug: false, 
                                   appId: '{3}', 
                                   timestamp:{0} , 
                                   nonceStr:'{1}', 
                                   signature:'{2}',
                                   jsApiList: [{4}] 
                               }});", timestamp, timestamp, signature, wxHelper.appid, parms);

        }
    }
}
